package com.android.webserver.security;

import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIUtils;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.protocol.HTTP;
import org.json.JSONObject;

import android.net.Uri;

import com.android.webserver.tornado.Request;
import com.android.webserver.tornado.Response;

/**
 * @author Chinmay Soman
 *
 */
public class SCSP {

	private static final String reportAddr = "http://localhost:8080/hello/report";

	static protected void sendJson(final String request, final String headers, final String blockedUri) {
		HttpClient client = new DefaultHttpClient();
		HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000);
		HttpResponse response;
		JSONObject json = new JSONObject();
		try{
			URI reportUri = new URI(reportAddr);
			HttpPost post = new HttpPost(reportUri);
			json.put("request", request);
			json.put("headers", headers);
			json.put("blocked-uri", blockedUri);
			json.put("violated-directive", "allow 'self'");
			json.put("original-policy", "allow 'self'");
			StringEntity se = new StringEntity( "csp-report: " + json.toString());  
			se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
			post.setEntity(se);
			response = client.execute(post);
			/*Checking response */
			if(response!=null){
				InputStream in = response.getEntity().getContent(); //Get the data in the entity
			}
		} catch(Exception e){
			e.printStackTrace();
		}
    }
	
	static public void validateCSP (Request request, Response response) {
		// We need to verify that only 'self' domain is used for resources.

		if (!response.isHTML)
			return;
		
		String [] tags = {"<img", "<script", "<object", "<frame", "<media", "<font", "<style", "<xhr"};
		String selfDomain = "";
		URI reqUri;
		try {
			reqUri = new URI(request.getURI());
			selfDomain = reqUri.getHost();

			for (int i=0;i<tags.length;i++) {
				int ind = 0;
				ind = response.HTMLContent.indexOf(tags[0], ind);
				if (ind == -1)
					break;
				int endTag = response.HTMLContent.indexOf(">", ind);
				String checkTag = response.HTMLContent.substring(ind, endTag+1);

				if (checkTag.matches(tags[i] + "\\s*[^>]*src\\s*=\\s*\"[http:\\/\\/]*((?!"+selfDomain+").)*[^\"\\/?]*\"[^>]*>")) {
					int srcStart = checkTag.indexOf("src");
					srcStart += 3;
					while (checkTag.charAt(srcStart) != '\"')
						srcStart++;
					srcStart++;
					int srcEnd = checkTag.indexOf("\"", srcStart);
					String blockedUri = checkTag.substring(srcStart, srcEnd);
					sendJson(request.getFullPath(), request.getRawHeaders(), blockedUri);
				}
			}

			// 1) img tag
			response.HTMLContent = response.HTMLContent.replaceAll(
					"<img\\s*[^>]*src\\s*=\\s*\"[http:\\/\\/]*((?!"+selfDomain+").)*[^\"\\/?]*\"[^>]*>", 
			" ");

			// 2) script tag
			response.HTMLContent = response.HTMLContent.replaceAll(
					"<script\\s*[^>]*src\\s*=\\s*\"[http:\\/\\/]*((?!"+selfDomain+").)*[^\"\\/?]*\"[^>]*>", 
			" ");

			// 3) object tag
			response.HTMLContent = response.HTMLContent.replaceAll(
					"<object\\s*[^>]*src\\s*=\\s*\"[http:\\/\\/]*((?!"+selfDomain+").)*[^\"\\/?]*\"[^>]*>", 
			" ");

			// 4) Frame tag
			response.HTMLContent = response.HTMLContent.replaceAll(
					"<frame\\s*[^>]*src\\s*=\\s*\"[http:\\/\\/]*((?!"+selfDomain+").)*[^\"\\/?]*\"[^>]*>", 
			" ");

			// 5) media tag
			response.HTMLContent = response.HTMLContent.replaceAll(
					"<media\\s*[^>]*src\\s*=\\s*\"[http:\\/\\/]*((?!"+selfDomain+").)*[^\"\\/?]*\"[^>]*>", 
			" ");

			// 6) font tag
			response.HTMLContent = response.HTMLContent.replaceAll(
					"<font\\s*[^>]*src\\s*=\\s*\"[http:\\/\\/]*((?!"+selfDomain+").)*[^\"\\/?]*\"[^>]*>", 
			" ");

			// 7) xhr tag
			response.HTMLContent = response.HTMLContent.replaceAll(
					"<xhr\\s*[^>]*src\\s*=\\s*\"[http:\\/\\/]*((?!"+selfDomain+").)*[^\"\\/?]*\"[^>]*>", 
			" ");

			// 8) style tag
			response.HTMLContent = response.HTMLContent.replaceAll(
					"<style\\s*[^>]*src\\s*=\\s*\"[http:\\/\\/]*((?!"+selfDomain+").)*[^\"\\/?]*\"[^>]*>", 
			" ");

			response.modifyHeader("Content-Length: " + response.HTMLContent.length());
			
		} catch (URISyntaxException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
